import Vue from "vue";
import axios from "axios";
import JSONbig from 'json-bigint'
import router from "@/router";
import store from "@store";
import { table } from "@/api";
// import batchExecutor from "./batch";
import TableScheduler from "./scheduler.js";
// import contractQuotationExecutor from './dialogRouter';
import { transformData } from './util';
import {
  // useResourceExecutor,
  registerExecutor,
  // registerLinkExecutor,
  // registerTargetExecutor
} from "@tablra";

class EnableExecutor {
  constructor() { }
  async schedule ({ url, data, transform }, context) {
    console.log("Enable:", { url, data, transform })
    let response = await axios.put(url, transformData(data, transform));
    if (response.code === 0) {
      Vue.prototype.$message({ type: "success", message: "启用成功" });
      context.search();
      return response;
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
}

class DisableExecutor {
  constructor() { }
  async schedule ({ url, data, transform }, context) {
    console.log("Disable:", { url, data, transform, context })
    let response = await axios.put(url, transformData(data, transform));
    if (response.code === 0) {
      Vue.prototype.$message({ type: "success", message: "禁用成功" });
      context.search();
      return response;
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
}

class DeleteExecutor {
  constructor() { }
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  async confirm ({ url, data, transform }, context) {
    let parsedUrl = this.parseUrl(url, data);
    let response = await axios.delete(parsedUrl, {
      data: transformData(data, transform)
    });
    if (response.code === 0) {
      Vue.prototype.$message({ type: "success", message: "删除成功" });
      context.search();
      return response;
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
  schedule ({ url, data, transform }) {
    Vue.prototype
      .$confirm("确定删除?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
      .then(() => {
        this.confirm({ url, data, transform });
      })
      .catch(() => {
        Vue.prototype.$message({
          type: "info",
          message: "取消删除"
        });
      });
  }
}

class AgreeExecutor {
  constructor() { }
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  async confirm ({ url, data, transform }, context) {
    let parsedUrl = this.parseUrl(url, data);
    let response =
      transform && transform.requestType
        ? await axios.put(parsedUrl, transformData(data, transform))
        : await axios.post(parsedUrl, transformData(data, transform));
    Vue.prototype.$message({ type: "success", message: "操作成功" });
    context.search();
    return response;
  }
  schedule ({ url, data, transform }) {
    Vue.prototype
      .$confirm("确定同意?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
      .then(() => {
        this.confirm({ url, data, transform });
      })
      .catch(() => {
        // Vue.prototype.$message({
        //   type: 'info',
        //   message: '取消同意'
        // });
      });
  }
}
// 签收
class ConfirmExecutor {
  constructor() { }
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }
    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  transformData (data, transform) {
    let target = {}
    for (let [name, value] of Object.entries(transform)) {
      target[name] = data[value]
    }
    return target
  }
  async confirm ({ url, data, preset, transform }, context) {
    let parsedUrl = this.parseUrl(url, data);
    let response = null;
    if (preset && preset.requestType) {
      response = await axios.put(parsedUrl, this.transformData(data, transform));
    } else {
      response = await axios.post(parsedUrl, this.transformData(data, transform));
    }
    if (response.code === 0) {
      Vue.prototype.$nextTick(() => {
        setTimeout(() => {
          context.search();
        }, 1000);
        Vue.prototype.$message({ type: "success", message: "操作成功" });
        /* {mode} 详情页面需要关闭当前页 */
        if (preset.mode) {
          setTimeout(() => {
            window.close();
          }, 1000);
        }
        /**
         *  router   参数  需要跳转的页面路径
         * **/
        if (preset.router) {
          let params = {
            mode: response.data.mode,
            status: response.data.status,
            templateId: response.data.templateId,
            customerType: preset.customerType
          };
          router.push({
            name: preset.router,
            query: params
          });
        }
      });
      return response;
    } else if (response.code == -10341) {
      if (preset.close) {
        //跳转运单合单详情
        Vue.prototype
          .$confirm(`${response.message}`, "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning"
          })
          .then(() => {
            let query = {
              combineId: data.combineId,
              status: 99
            };
            const { href } = router.resolve({
              name: "oneBillDetails",
              query
            });
            window.open(href, "_blank");
          })
          .catch(() => { });
      }
    }
  }

  // 报价前置校验
  async quoteValidate ({ url, data, preset, transform }, context) {
    let response = await axios.get(`/quotation/validate/${data.subjectId}`);
    if (response.code === 0) {
      if (response.data.validate) {
        if (preset.quoteType === "1") {
          if (preset?.isMatch || preset?.isRefresh) {
            this.quoteMatchValidate(url, data, preset, transform, 1);
          } else {
            this.onJump({ ...preset, ...data }, 1);
          }
        } else {
          this.handleConfirm({ url, data, preset, transform });
        }
      } else if (response.data.flag === 1) {
        // flag:1 已经有人发起了报价
        Vue.prototype
          .$confirm(`已向您发起了报价，是否去审核?`, "提示", {
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type: "warning"
          })
          .then(() => {
            let quotationId = response.data?.quotationId || data.quotationId;
            this.onJump({ ...preset, ...data, quotationId }, 2);
          });
      } else if (response.data.flag === 2) {
        // flag:2 我已经发起了报价
        Vue.prototype
          .$confirm("不能重复报价，请刷新页面?", "提示", {
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type: "warning"
          })
          .then(() => {
            context.search();
          });
      }
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
  // 报价是否能够匹配合约前置校验
  async quoteMatchValidate (url, rowData, preset, transform, type) {
    let reqsUrl = preset?.isRefresh ? `/quotation/template/refresh` : `/quotation/template/match`
    let response = await axios.post(reqsUrl, { subjectId: rowData.subjectId });
    let { data } = response;
    // console.log('-----', data, transform, preset)
    if (preset?.isRefresh) {
      // 价格重算
      if (data.refresh) {
        return tableFrameExecutor.schedule({ url, data: rowData, preset: { ...preset, ...data, name: preset.dialogName }, transform, batchEntry: [], title: preset?.title });
      } else {
        return Vue.prototype.$message({ type: "warning", message: "未匹配到新的合约" });
      }
    } else {
      // 合约匹配
      if (data.match) {
        return tableFrameExecutor.schedule({ url, data: rowData, preset: { ...preset, ...data, name: preset.dialogName }, transform, batchEntry: [], title: preset?.title });
      } else {
        this.onJump({ ...preset, ...rowData }, type);
      }
    }
  }
  schedule ({ url, data, preset, transform }, context) {
    if (preset?.quoteValidate) {
      if (data?.combineContractNo) {
        router.push({
          name: "oneBillQuote",
          query: {
            combineId: data.combineId,
            contractNo: data.combineContractNo,
            subjectId: data.subjectId,
            status: 10
          }
        });
      } else {
        this.quoteValidate({ url, data, preset, transform }, context);
      }
    } else {
      this.handleConfirm({ url, data, preset, transform }, context);
    }
  }
  handleConfirm ({ url, data, preset, transform }, context) {
    Vue.prototype
      .$confirm(
        `${preset?.custom ? preset.label : "确认" + preset.label}?`,
        "提示",
        {
          confirmButtonText: "确认",
          cancelButtonText: "取消",
          type: "warning"
        }
      )
      .then(() => {
        this.confirm({ url, data, preset, transform }, context);
      });
  }
  onJump (data, type) {
    let query = {
      quotationId: data.quotationId,
      combineId: data.combineId,
      waybillId: data.waybillId,
      surcharge: data?.surcharge,
      subjectId: data?.subjectId,
      contractNo: data?.contractNo,
      customerName: data?.customerName,
      status: type === 1 ? data.status : "11"
    };
    if (data.quoteType) query.quoteType = type === 1 ? data.quoteType : "7";
    router.push({
      name: data.name || "quoteDetail",
      query
    });
  }
}
// 关单、备注等textarea 弹窗
class PromptExecutor {
  constructor() { }
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  async confirm ({ url, data, preset, transform, value }, context) {
    let parsedUrl = this.parseUrl(url, data);
    let response = null;
    if (preset && preset.requestType) {
      response = await axios.put(
        parsedUrl,
        Object.assign({ [preset.name]: value }, transformData(data, transform))
      );
      /* {mode} 详情页面需要关闭当前页 */
      if (preset.mode) {
        Vue.prototype.$message({ type: "success", message: "操作成功" });
        setTimeout(() => {
          window.close();
        }, 1000);
      }
    } else {
      response = await axios.post(
        parsedUrl,
        Object.assign({ [preset.name]: value }, transformData(data, transform))
      );
      /* {mode} 详情页面需要关闭当前页 */
      if (preset.mode) {
        Vue.prototype.$message({ type: "success", message: "操作成功" });
        setTimeout(() => {
          window.close();
        }, 1000);
      }
    }
    // let response = await axios.post(parsedUrl, Object.assign({ [preset.name]: value }, transformData(data, transform)));
    context.search();
    Vue.prototype.$message({ type: "success", message: "操作成功" });
    return response;
  }

  schedule ({ url, data, preset, transform }) {
    Vue.prototype
      .$prompt("", `${preset.label}` || "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        inputType: "textarea",
        inputPattern: /^.{1,200}$/,
        inputPlaceholder: `请输入${preset.label}`,
        inputErrorMessage: `${preset.label}不能为空,且不能超过200个字符`
      })
      .then(({ value }) => {
        this.confirm({ url, data, preset, transform, value });
      })
      .catch(() => { });
  }
}

class LinkExecutor {
  transformData (data, transform) {
    let target = {}
    for (let [name, alias] of Object.entries(transform)) {
      target[name] = data[alias];
    }
    return target
  }
  async confirm ({ url, data, preset, transform }) {
    if (preset.type) {
      router.push({
        name: preset.routeName,
        query: Object.assign(
          { type: preset.type },
          this.transformData(data, transform)
        )
      });
    } else if (preset.mark === '_blank') {
      const { href } = router.resolve({
        name: preset.routeName,
        // query: { ...this.transformData(data, transform), ...preset }
      });
      let params = { ...this.transformData(data, transform), ...preset }
      sessionStorage.setItem('ROUTEER_OPEN_PARAMS', JSON.stringify(params))
      window.open(href, "_blank");
    } else {
      let response = await axios.get(`${url}${data.orderId}`);
      if (response.code === 0) {
        if (response.data) {
          this._messageBox();
        } else {
          router.push({
            name: preset.routeName,
            query: Object.assign(
              { type: preset.type },
              transformData(data, transform)
            )
          });
        }
        Vue.prototype.$message({ type: "success", message: "操作成功" });
        return response;
      }
    }
  }
  _messageBox () {
    Vue.prototype
      .$confirm(
        "货物信息已做了异常物品数量登记，确定修改后会清除!",
        "温馨提示",
        {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        }
      )
      .then(() => {
        router.push({
          name: preset.routeName,
          query: Object.assign(
            { type: preset.type },
            transformData(data, transform)
          )
        });
        // this.confirm({ url, data, preset, transform })
      })
      .catch(() => {
        Vue.prototype.$message({
          type: "info",
          message: "已取消"
        });
      });
  }
  schedule ({ url, data, preset, transform }) {
    console.log("Link :", { url, data, preset, transform });
    this.confirm({ url, data, preset, transform });
  }
}

class RejectExecutor {
  constructor() { }
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  async confirm ({ url, data, transform }) {
    let parsedUrl = this.parseUrl(url, data);
    let response = await axios.put(parsedUrl, transformData(data, transform));
    Vue.prototype.$message({ type: "success", message: "操作成功" });
    return response;
  }
  schedule ({ url, data, transform }) {
    Vue.prototype
      .$confirm("确定拒绝?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
      .then(() => {
        this.confirm({ url, data, transform });
      })
      .catch(() => {
        Vue.prototype.$message({
          type: "info",
          message: "取消拒绝"
        });
      });
  }
}

class DetailsDialogExecutor {
  constructor() { }
  async schedule ({ url, data, preset, transform }) {
    store.commit("customer/CUSTOMER_DETAILS_LABEL", preset);
    const params = {
      url: url,
      customerId: Object.values(transformData(data, transform))[0],
      data: data,
    };
    store.dispatch("customer/details", params);
  }
}

// class FormDisabledExecutor {
//   constructor() { }
//   async schedule ({ preset, type }) {
//     store.commit("form/FORM_ITEM_DISABLED", preset);
//     store.commit("form/OPER_STATUS", type);
//   }
// }

class FormContainerExecutor {
  constructor() { }
  schedule ({ url, data, preset, transform }) {
    store.dispatch("table/drawerTrueActions");

    const config = {
      url: url,
      param: transformData(data, transform),
      childName: preset
    };
    store.commit("table/FORMCONTAINERINFO", config);
  }
}

class TableFrameExecutor {
  constructor() { }
  schedule ({ url, data, preset, transform, batchEntry, title }) {
    store.dispatch("table/visibleTrueActions");
    console.log("Table frame: ", batchEntry)
    const config = {
      url: url,
      param: transformData(data, transform),
      transform: transform,
      childName: preset,
      tableMultiple: batchEntry,
      title: title
    };
    store.commit("table/FORMCONTAINERINFO", config);
    // context.search();
  }
}

class TransportExecutor {
  constructor() { }
  async getOrderStatus ({ url, data, preset, transform, title }) {
    let response = await axios.get(`/transport/waybill/${data.id}/order`);
    if (response.code === 0 && response.data) {
      if ([30, 40].includes(response.data?.status)) {
        return Vue.prototype.$message({
          type: "error",
          message: "订单已签收，不能进行操作"
        });
      } else if (response.data?.status === 50) {
        return Vue.prototype.$message({
          type: "error",
          message: "订单已关单，不能进行操作"
        });
      } else {
        this.handleBinded({ url, data, preset, transform, title });
      }
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }

  handleBinded ({ url, data, preset, transform, title }) {
    store.dispatch("dialog/bindVisibleTrueActions");
    let target = {}
    if (transform) {
      for (let [name, value] of Object.entries(transform)) {
        target[name] = data[value]
      }
    }
    const config = {
      url: url,
      param: target,
      childName: preset,
      title: title
    };
    store.commit("dialog/TRANSPORT_CONFIG", config);
  }

  schedule ({ url, data, preset, transform, title }) {
    if (preset?.transportType === "waybill") {
      this.getOrderStatus({ url, data, preset, transform, title });
    } else {
      this.handleBinded({ url, data, preset, transform, title });
    }
  }
}

class EnrollAgreeExecutor {
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  async confirm (url, data, transform) {
    let parsedUrl = this.parseUrl(url, data);
    let response = await axios.post(parsedUrl, transformData(data, transform));
    if (response.code === 0) {
      Vue.prototype.$message({ type: "success", message: "操作成功" });
      return response;
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
  schedule ({ url, data, transform }, context) {
    Vue.prototype
      .$confirm("确定同意?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
      .then(() => {
        // let url = `/user/register/tenantAgree`
        this.confirm(url, data, transform);
        context.search();
      })
      .catch(() => {
        // Vue.prototype.$message({
        //   type: 'info',
        //   message: '取消同意'
        // });
      });
  }
}

class EnrollRefuseExecutor {
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  async confirm (url, data, transform, content) {
    let parsedUrl = this.parseUrl(url, data);
    let params = Object.assign(transformData(data, transform), content);
    let response = await axios.post(parsedUrl, params);
    if (response.code === 0) {
      Vue.prototype.$message({ type: "success", message: "操作成功" });
      return response;
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
  schedule ({ url, data, transform }, context) {
    Vue.prototype
      .$prompt("请输入拒绝原因", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        inputValidator: true,
        inputErrorMessage: "请输入拒绝原因"
      })
      .then(({ value }) => {
        let content = { rejectReason: value };
        // let url = `/user​/register​/tenantReject`
        this.confirm(url, data, transform, content);
        context.search();
      })
      .catch(() => {
        Vue.prototype.$message({
          type: "info",
          message: "取消拒绝"
        });
      });
  }
}

class EnrollRemarksExecutor {
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  async confirm (url, data, transform, content) {
    let parsedUrl = this.parseUrl(url, data);
    let params = Object.assign(transformData(data, transform), content);
    let response = await axios.put(parsedUrl, params);
    if (response.code === 0) {
      Vue.prototype.$message({ type: "success", message: "操作成功" });
      return response;
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
  schedule ({ url, data, transform }, context) {
    Vue.prototype
      .$prompt("请输入备注", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        inputValidator: true,
        inputErrorMessage: "请输入备注内容"
      })
      .then(({ value }) => {
        let content = { remarks: value };
        this.confirm(url, data, transform, content);
        context.search();
      })
      .catch(() => {
        Vue.prototype.$message({
          type: "info",
          message: "取消备注"
        });
      });
  }
}

class TargetRouter {
  intercept (url) {
    let regex = /\/\/target:(?<scope>\w+)/;
    let {
      groups: { scope }
    } = regex.exec(url);
    return scope;
  }
  // 刷新batchEntry
  async handleAction (action) {
    let response = await TableScheduler.schedule(
      router?.currentRoute?.params?.menuId,
      action
    );
    if (response?.code === 0) {
      console.log("刷新batchEntry");
    }
  }
  schedule ({ url, data, transform, batchEntry }) {
    let query = transformData(data, transform);
    router.push({
      name: this.intercept(url),
      query,
      params: {
        ...data,
        batchEntry,
        ...transform,
      }
    });
    if (batchEntry?.length > 0) {
      this.handleAction([]);
    }
  }
}

class LinkRouter {
  intercept (url) {
    let regex = /\/\/link:(?<scope>\w+)/;
    let {
      groups: { scope }
    } = regex.exec(url);
    return scope;
  }
  async quoteValidate ({ url, data, preset, transform }, context) {
    let response = await axios.get(`/quotation/validate/${data.subjectId}`);
    if (response.code === 0) {
      if (response.data.validate) {
        this.onJump({ url, ...preset, ...data }, 1);
      } else if (response.data.flag === 1) {
        // flag:1 已经有人发起了报价
        Vue.prototype
          .$confirm(`已向您发起了报价，是否去审核?`, "提示", {
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type: "warning"
          })
          .then(() => {
            let quotationId = response.data?.quotationId || data.quotationId;
            this.onJump({ ...preset, ...data, quotationId }, 2);
          });
        // flag:2 我已经发起了报价
      } else if (response.data.flag === 2) {
        Vue.prototype
          .$confirm("不能重复报价，请刷新页面?", "提示", {
            confirmButtonText: "确认",
            cancelButtonText: "取消",
            type: "warning"
          })
          .then(() => {
            context.search();
          });
      }
    } else {
      Vue.prototype.$message({ type: "error", message: response.message });
    }
  }
  schedule ({ url, data, preset = {}, transform }) {
    // let query = transformData(data, transform);
    /* 不需要带上全部行参数 */
    let target = {};
    if (transform) {
      for (let [name, alias] of Object.entries(transform)) {
        target[name] = data[alias];
      }
    }

    if (preset?.quoteValidate) {
      this.quoteValidate({ url, data, preset, transform });
    } else if (preset?.onebillPay && data.combineContractNo) {
      Vue.prototype
        .$confirm(`运单属于合单（合单号：(${data.combineContractNo})的子单，将以合单进行${preset?.billType === 1 ? '收' : '付'}款`, "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
        .then(() => {
          if (preset.transform && preset.transform.custom) { target = { ...target, ...preset.transform, isOneBill: 1 }; }
          router.push({
            name: preset.routeName,
            query: { ...target }
          });
        })
    } else {
      if (preset.transform?.bargain) {
        if (data?.surcharge) {
          preset.transform.status = "88";
          target.surcharge = true;
        } else {
          preset.transform.status = "99";
        }
      }
      if (preset.transform && preset.transform.custom) {
        target = { ...target, ...preset.transform };
      }
      if (preset?.linkType && preset?.linkType === "_blank") {
        const { href } = router.resolve({
          name: preset.routeName || this.intercept(url),
          query: { ...target, ...preset }
        });
        window.open(href, "_blank");
      } else {
        router.push({
          name: preset.routeName || this.intercept(url),
          query: { ...target, ...preset }
        });
      }
    }
  }
  onJump (data, type) {
    let queryInfo = {
      quotationId: data.quotationId,
      waybillId: data.waybillId,
      surcharge: data?.surcharge,
      subjectId: data?.subjectId,
      status: type === 1 ? data.status : "11"
    };
    if (data.quoteType) queryInfo.quoteType = type === 1 ? data.quoteType : "7";
    router.push({
      name: this.intercept(data.url),
      query: { ...queryInfo }
    });
  }
}

const createWaybillVaild = (url, data, preset, transform, batchEntry) => {
  if (batchEntry.length > 0) {
    let cstFlag = false;
    let carrFlag = false;
    let customerName = batchEntry[0].customerName;
    let carrierName = batchEntry[0].carrierName;
    batchEntry.map((item) => {
      if (transform.createType === 1 && customerName != item.customerName) {
        return (cstFlag = true);
      }
      if (transform.createType === 2 && carrierName != item.carrierName) {
        return (carrFlag = true);
      }
    });
    if (cstFlag || carrFlag) {
      if (cstFlag)
        return Vue.prototype.$message({
          type: "warning",
          message: "勾选的运单，不是同一个发货方"
        });
      else
        return Vue.prototype.$message({
          type: "warning",
          message: "勾选的运单，不是同一个承运方"
        });
    } else {
      return targetRouter.schedule({
        url: `//target:${url}`,
        data,
        preset,
        transform,
        batchEntry
      });
    }
  } else {
    Vue.prototype.$message({ type: "warning", message: "请选择至少一条数据" });
  }
};

class BatchSignExecutor {
  schedule ({ data, ...kwargs }, context) {
    const { selection } = data;
    if (selection.length > 10) {
      Vue.prototype.$message({
        type: "warning",
        message: "最多只能勾选10条数据"
      });
      return;
    } else if (selection.length <= 0) {
      Vue.prototype.$message({
        type: "warning",
        message: "请选择至少一条数据"
      });
      return;
    }
    // return batchExecutor.schedule({ batchEntry: selection, ...kwargs }, context);
  }
}

class BatchReceiptExecutor {
  schedule ({ data, ...kwargs }, context) {
    const { selection } = data;
    if (selection.length <= 0) {
      Vue.prototype.$message({
        type: "warning",
        message: "请选择至少一条数据"
      });
      return;
    }
    return tableFrameExecutor.schedule({ batchEntry: selection, ...kwargs }, context);
  }
}

class BatchOnebillExecutor {
  schedule ({ data, url, ...kwargs }, context) {
    const { selection } = data;
    if (selection.length > 100) {
      return Vue.prototype.$message({
        type: "warning",
        message: "最多可选择100单合单"
      });
    }

    if (selection.length <= 0) {
      {
        Vue.prototype.$message({
          type: "warning",
          message: "请选择2单以上再合单"
        });
      }
      return;
    }

    return targetRouter.schedule({
      url: `//target:${url}`,
      ...kwargs,
      batchEntry: selection
    });
  }
}

// 下载
class DownloadExecutor {
  constructor() { }
  async confirm ({ kwargs, data }, context) {
    const jsonStr = `{ "art_id": ${data.certId} }`
    let params = {
      certId: JSONbig.parse(jsonStr).art_id.toString(),
      downloadSource: 3,
      fileType: 2,
      ip: '192.168.1.43:8080'         // 暂时写死
    }
    let response = await axios.post(kwargs.url, params)
    let { count, url } = response.data
    window.location.href = url
    Vue.prototype.$message({ type: "success", message: `操作成功，剩余${count || 0}次下载次数` });
    context.search();
    return response;
  }
  schedule ({ data, ...kwargs }, context) {
    this.confirm({ kwargs, data }, context)
  }
}

class ReconciliationExecutor {
  schedule (args) {
    const { url, data, preset, transform } = args;
    const { selection: batchEntry } = data;
    return createWaybillVaild(url, data, preset, transform, batchEntry);
  }
}

// 刷新
class RefreshExecutor {
  parseUrl (url, data) {
    if (!url || !data) {
      return url;
    }

    for (let [name, value] of Object.entries(data)) {
      let pattern = "${" + name + "}";
      url = url.replace(pattern, value);
    }
    return url;
  }
  parseParams (data, transform) {
    let target = {}
    for (let [name, value] of Object.entries(transform)) {
      target[name] = data[value]
    }
    return target
  }
  async confirm ({ kwargs, data }, context) {
    /* waybillRefresh 代表运单刷新反之为 订单货物跟踪刷新 */
    let isWaybillRefresh = kwargs.preset.waybillRefresh
    let refreshType = isWaybillRefresh ? [30, 40, 50] : [40, 50]
    if (!data.deviceCode || data.deviceCode === "") {
      return Vue.prototype.$message.error(`${isWaybillRefresh ? '运单' : '订单'}未绑定设备`);
    }
    if (refreshType.includes(data.status)) {
      return Vue.prototype.$message.error(`${isWaybillRefresh ? '运单' : '订单'}已签收，不能刷新`);
    }
    let parseUrl = this.parseUrl(kwargs.url, data)
    let response = await isWaybillRefresh ? axios.post(parseUrl, this.parseParams(data, kwargs.transform)) : axios.put(parseUrl)
    Vue.prototype.$message.success('操作成功');
    context.search();
    return response;
  }
  schedule ({ data, ...kwargs }, context) {
    this.confirm({ kwargs, data }, context)
  }
}

class RecordExport {
  schedule ({ url, data, preset, transform }) {
    let ht = JSON.parse(window.localStorage.ht);
    // let args = transformData(data, transform)
    let params = {
      args: { billId: data.billId, tenantId: ht.login?.tenantId },
      name: `${preset.name}${new Date().format("yyyyMMddhhmmss")}`,
      type: preset.exportType
    };
    this.containerExport(url, params)
  }
  async containerExport (url, params) {
    await table.submitFormContainer(url, params);
    store.dispatch("login/exportCount");
    Vue.prototype.$message({
      type: "success",
      message: "导出功能正在后台执行中，请稍后去“导出文件”下载中查看！"
    });
  }
}

const linkRouter = new LinkRouter();
const targetRouter = new TargetRouter();
const enableExecutor = new EnableExecutor();
const disableExecutor = new DisableExecutor();
const deleteExecutor = new DeleteExecutor();
const detailsDialogExecutor = new DetailsDialogExecutor();
const formContainerExecutor = new FormContainerExecutor();
const tableFrameExecutor = new TableFrameExecutor();
const agreeExecutor = new AgreeExecutor();
const rejectExecutor = new RejectExecutor();
const linkExecutor = new LinkExecutor();
const confirmExecutor = new ConfirmExecutor();
const promptExecutor = new PromptExecutor();
const transportExecutor = new TransportExecutor();
const enrollAgreeExecutor = new EnrollAgreeExecutor();
const enrollRefuseExecutor = new EnrollRefuseExecutor();
const enrollRemarksExecutor = new EnrollRemarksExecutor();
const batchSignExecutor = new BatchSignExecutor();
const batchOnebillExecutor = new BatchOnebillExecutor();
const batchReceiptExecutor = new BatchReceiptExecutor();
const reconciliationExecutor = new ReconciliationExecutor();
const recordExport = new RecordExport();
const downloadExecutor = new DownloadExecutor();
const refreshExecutor = new RefreshExecutor()

export function registerExecutors () {
  registerExecutor("enable", (data, context) => enableExecutor.schedule(data, context));
  registerExecutor("disable", (data, context) => disableExecutor.schedule(data, context));
  registerExecutor("delete", (data, context) => deleteExecutor.schedule(data, context));
  registerExecutor("view", (data, context) => detailsDialogExecutor.schedule(data, context));
  registerExecutor("agree", (data, context) => agreeExecutor.schedule(data, context));
  registerExecutor("reject", (data, context) => rejectExecutor.schedule(data, context));
  registerExecutor("dialog", (data, context) => tableFrameExecutor.schedule(data, context));
  // registerExecutor("dialog_router", (data, context) =>
  //   contractQuotationExecutor.schedule(data, context)
  // );
  registerExecutor("enroll_agree", (data, context) =>
    enrollAgreeExecutor.schedule(data, context)
  );
  registerExecutor("enroll_refuse", (data, context) =>
    enrollRefuseExecutor.schedule(data, context)
  );
  registerExecutor("enroll_remark", (data, context) =>
    enrollRemarksExecutor.schedule(data, context)
  );
  registerExecutor("link", (data, context) => linkExecutor.schedule(data, context));
  registerExecutor("confirm", (data, context) => confirmExecutor.schedule(data, context));
  registerExecutor("prompt", (data, context) => promptExecutor.schedule(data, context));
  registerExecutor("batch_sign", (data, context) => batchSignExecutor.schedule(data, context));
  registerExecutor("batch_receipt", (data, context) =>
    batchReceiptExecutor.schedule(data, context)
  );
  registerExecutor("batch_bind", (data, context) => batchReceiptExecutor.schedule(data, context));
  registerExecutor("batch_onebill", (data, context) =>
    batchOnebillExecutor.schedule(data, context)
  );
  registerExecutor("form_container", (data, context) =>
    formContainerExecutor.schedule(data, context)
  );
  registerExecutor("transport_dialog", (data, context) =>
    transportExecutor.schedule(data, context)
  );
  registerExecutor("create_reconciliation", (data, context) =>
    reconciliationExecutor.schedule(data, context)
  );
  registerExecutor("import", ({ url }) => {
    router.push({ path: url });
  });
  registerExecutor("export", ({ url }) => {
    router.push({ path: url });
  });
  registerExecutor("download", (data, context) =>
    downloadExecutor.schedule(data, context)
  );
  registerExecutor("refresh", (data, context) =>
    refreshExecutor.schedule(data, context)
  );
  // registerExecutor("setup", (data) => {
  //   console.log("Setup:", data);
  // });
  registerExecutor("invite-driver", (data) => {
    console.log("Invite driver:", data);
  });
  registerExecutor("invite-supplier", (data) => {
    console.log("Invite supplier:", data);
  });
  registerExecutor(("record_export"), (data) =>
    recordExport.schedule(data)
  );
  // registerLinkExecutor((data) => linkRouter.schedule(data));
  // registerTargetExecutor((data) => targetRouter.schedule(data));
}

// const resourceExecutor = useResourceExecutor();
export default {
  schedule (menuId, action, data) {
    // TODO: 这个代码不知道有什么用？ 
    // formDisabledExecutor.schedule(action)
    // return resourceExecutor({ menuId, data, ...action });
  }
};
